import { Asset, AssetManager, assetManager, AudioClip, Constructor, Prefab } from "cc";
/** 单例模式的资源管理器 */
export class ResManager {
    /**
     * 加载 Asset Bundle 接口
     * @param bundleName Asset Bundle 的名称
     * @param cb 可选回调
     */
    loadBundle(bundleName: string, cb?: (bundle: AssetManager.Bundle | null) => void) {
        assetManager.loadBundle(bundleName, (e, bundle) => {
            cb && cb(bundle);
        });
    }

    /**
     * 加载 Asset Bundle 接口
     * @param bundleName 
     * @returns 
     */
    loadBundleAsync(bundleName: string): Promise<AssetManager.Bundle> {
        return new Promise<AssetManager.Bundle>(rs => {
            this.loadBundle(bundleName, rs);
        })
    }

    loadPrefab(bundleName: string, prefabPath: string, cb: (prefab: Prefab | null) => void) {
        assetManager.loadBundle(bundleName, (e, bundle) => {
            bundle.load(prefabPath, Prefab, (err, prefab: Prefab) => {
                if (err) {
                    console.error(err);
                    cb(null);
                    return;
                }
                cb(prefab)
            })
        })
    }

    loadAudioClip(bundleName: string, audioPath: string, cb: (asset: AudioClip | null) => void) {
        assetManager.loadBundle(bundleName, (e, bundle) => {
            bundle.load(audioPath, AudioClip, (err, asset: AudioClip) => {
                if (err) {
                    console.error(err);
                    cb(null);
                    return;
                }
                cb(asset)
            })
        })
    }

    loadPrefabByBUrl(bUrl: IBundleUrl, cb: (prefab: Prefab | null) => void) { this.loadPrefab(bUrl.b, bUrl.l, cb); }
    loadAudioByBUrl(bUrl: IBundleUrl, cb: (audioClip: AudioClip | null) => void) { this.loadAudioClip(bUrl.b, bUrl.l, cb); }

    loadAssetAsync<T extends Asset>(bUrl: IBundleUrl, type: Constructor<T> | null) {
        return new Promise<T>(rs => {
            assetManager.loadBundle(bUrl.b, (e, bundle) => {
                bundle.load(bUrl.l, type, (err, _asset) => {
                    if (err) {
                        console.error(err);
                        return rs(null);
                    }
                    rs(_asset)
                })
            })
        })
    }
}